package com.rw.coco.handler;

import com.rw.coco.api.bot.handler.MessageHandler;
import com.rw.coco.api.data.CocoDataApi;
import com.rw.coco.api.event.MessageEvent;
import com.rw.coco.api.log.CocoLogger;
import com.rw.coco.api.reply.CocoReplyApi;
import com.rw.coco.handler.message.event.CocoMessageEvent;
import com.rw.coco.handler.message.reply.ReplyFilter;
import com.rw.coco.handler.message.reply.ReplyHandler;
import com.rw.coco.handler.message.reply.handler.transaction.TransactionAble;
import com.rw.coco.handler.message.reply.handler.validate.*;
import com.rw.coco.handler.message.reply.util.DiceHandlerListUtil;
import com.rw.coco.handler.message.reply.util.NormalHandlerUtil;
import com.rw.coco.util.CocoData;
import com.rw.coco.util.TransactionUtil;
import com.rw.coco.util.config.CocoConfig;
import com.rw.tool.util.string.StringFormatter;

import java.util.ArrayList;
import java.util.List;

/**
 * 消息触发器
 */
public class CocoMessageHandler implements MessageHandler {
    // api
    private final CocoDataApi dataApi;

    // logger
    private final CocoLogger cocologger;

    // logger
    private final CocoReplyApi replyApi;

    // cocoData
    private final CocoData cocoData;

    // 校验Handler列表
    private final List<ReplyHandler> validateHandlerList;

    // 骰娘指令Handler列表
    private final List<ReplyHandler> diceHandlerList;

    // 频率Handler列表
    private final List<ReplyHandler> frequencyHandlerList;

    public CocoMessageHandler(CocoDataApi dataApi, CocoReplyApi replyApi, CocoLogger cocologger,
                              CocoData cocoData) {
        this.dataApi = dataApi;
        this.cocologger = cocologger;
        this.replyApi = replyApi;
        this.cocoData = cocoData;
        CocoConfig cocoConfig = cocoData.getCocoConfig();

        // 配置校验列表
        validateHandlerList = new ArrayList<>();
        // 黑名单拦截
        validateHandlerList.add(new MessageLengthFilter(cocoConfig));
        // 退群、删好友指令
        validateHandlerList.add(new DismissReplyHandler());
        // 机器人总开关指令
        validateHandlerList.add(new SwitchOnOFFReplyHandler());
        // 黑名单指令
        validateHandlerList.add(new BlackListHandler(cocoConfig));
        // 黑名单拦截
        validateHandlerList.add(new BlackListFilter());
        // 机器人开关拦截
        validateHandlerList.add(new BotSwitchFilter());
        // 群聊开关处理器
        validateHandlerList.add(new GroupSwitchHandler());
        // 群聊开关过滤器
        validateHandlerList.add(new GroupSwitchFilter());

        // 配置骰娘指令列表
        List<ReplyHandler> diceHandlerList = new ArrayList<>();
        diceHandlerList.addAll(DiceHandlerListUtil.get(cocoConfig));
        diceHandlerList.addAll(NormalHandlerUtil.get(cocoConfig));

        this.diceHandlerList = diceHandlerList;

        // 配置频率列表
        frequencyHandlerList = new ArrayList<>();
        frequencyHandlerList.add(new GroupFrequencyHandler());
        frequencyHandlerList.add(new PrivateFrequencyHandler());
    }

    // 获取基本信息
    @Override
    public void handle(MessageEvent messageEvent) {
        CocoMessageEvent cocoMessageEvent = CocoMessageEvent.of(messageEvent, dataApi, replyApi, cocologger, cocoData);

        // 执行前置校验
        if (executeReplyHandler(validateHandlerList, cocoMessageEvent)) {
            return;
        }

        // 触发对话逻辑
        if (executeReplyHandler(diceHandlerList, cocoMessageEvent)) {
            // 频率校验
            executeFrequencyHandler(cocoMessageEvent);
            return;
        }

        // TODO 测试代码，上生产环境需要删除
        String msg = StringFormatter.format("运行结束，未执行任何回复，接受消息：{}", messageEvent.getMessage());
        cocoMessageEvent.getCocoLogger().info(msg);
        // ↑↑ 上生产环境需要删除 ↑↑
    }

    /**
     * 执行ReplyHandler列表
     * 若执行成功，则返回true
     * 若执行失败，则返回false
     */
    private boolean executeReplyHandler(List<ReplyHandler> replyHandlerList, CocoMessageEvent event) {
        for (ReplyHandler replyHandler : replyHandlerList) {
            if (replyHandler.trigger(event)) {
                if (replyHandler.getClass().getAnnotation(TransactionAble.class) == null) {
                    // 如果不需要开启事务
                    replyHandler.handler(event);
                } else {
                    // 如果需要开启事务
                    TransactionUtil.run(event, () -> replyHandler.handler(event));
                }

                // TODO 测试代码，上生产环境需要删除
                if (replyHandler instanceof ReplyFilter ||
                        replyHandler instanceof GroupSwitchFilter ||
                        replyHandler instanceof SwitchOnOFFReplyHandler ||
                        replyHandler instanceof GroupSwitchHandler
                ) {
                    String msg = StringFormatter.format("运行结束，被拦截器 {} 拦截，接受消息：{}",
                            replyHandler.getClass().getName(), event.getMessage());
                    event.getCocoLogger().info(msg);
                }
                // ↑↑ 上生产环境需要删除 ↑↑

                return true;
            }
        }
        return false;
    }

    /**
     * 执行频率限制
     */
    private void executeFrequencyHandler(CocoMessageEvent event) {
        for (ReplyHandler replyHandler : frequencyHandlerList) {
            if (replyHandler.trigger(event)) {
                replyHandler.handler(event);
            }
        }
    }
}
